using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml;
using System.Xml.XPath;

namespace DemoLib.Service.Web
{
    public class AuthorizationManager : ServiceAuthorizationManager {
        public override bool CheckAccess(
            OperationContext operationContext, ref Message message) {

            base.CheckAccess(operationContext, ref message);
            string action = operationContext.IncomingMessageHeaders.Action;

            if (action == "urn:msdnmag/IService/GetRoles") {
                // messags in WCF are always read-once
                // we create one copy to work with, and one copy for WCF
                MessageBuffer buffer = operationContext.RequestContext.RequestMessage.
                    CreateBufferedCopy(int.MaxValue);
                message = buffer.CreateMessage();

                // get the username value using XPath
                XPathNavigator nav = buffer.CreateNavigator();

                XmlNamespaceManager nsm = new StandardNamespaceManager(nav.NameTable);
                nsm.AddNamespace("msdn", "urn:msdnmag");

                XPathNavigator node = nav.SelectSingleNode("s:Envelope/s:Body/msdn:GetRoles/msdn:username", nsm);
                string parameter = node.InnerXml;

                // check authorization
                if (operationContext.ServiceSecurityContext.PrimaryIdentity.Name == parameter)
                {
                    return true;
                }
                else
                {
                    return (GetPrincipal(operationContext).IsInRole("administrators"));
                }
            }
            return true;
            }

        private IPrincipal GetPrincipal(OperationContext operationContext)
        {
            //return new CustomPrincipal();
            //return new GenericPrincipal();;
            throw new System.NotImplementedException();
        }

        // rest omitted
    }

    public class StandardNamespaceManager : XmlNamespaceManager
    {
        public StandardNamespaceManager(XmlNameTable nameTable)
            :base(nameTable)
        {
            throw new System.NotImplementedException();
        }
    }
}